package org.footito.android.tools;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.os.Environment;

public class FileLogger {
	private static final String LOG_NAME = "log.csv";
	private static final String LOG_HEAD = "time;lvl;pid;tag;message";
	private static final DateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
	private static final String DEFAULT_TAG = "null";
	private String logAbsolutePath;
	private File mLogFile;
	private Writer writer;
	private String mTag;

	/**
	 * Create a file for writing logs.
	 * 
	 * @param filePath
	 *            need to be the folder path from the sdcard
	 * @throws IOException
	 */
	public FileLogger(String filePath) throws IOException {
		String folderPathFromSdcard = Environment.getExternalStorageDirectory() + filePath;

		File logFolder = new File(folderPathFromSdcard);
		if (!logFolder.exists())
			logFolder.mkdir();
		if (!logFolder.isDirectory())
			throw new IOException("The filePath need to be a folder");
		if (!logFolder.canWrite())
			throw new IOException("The folder is not writable");

		logAbsolutePath = folderPathFromSdcard + File.separator + LOG_NAME;
		mLogFile = new File(logAbsolutePath);
		boolean needHead = false;
		if (!mLogFile.exists()) {
			needHead = true;
		}
		writer = new OutputStreamWriter(new FileOutputStream(mLogFile, true), "UTF-8");
		if (needHead) {
			writer.append(LOG_HEAD);
			writer.append('\n');
			writer.flush();
		}
	}

	/**
	 * Create a file for writing logs.
	 * 
	 * @param filePath
	 *            need to be the folder path from the sdcard
	 * @param tag
	 *            tag used for message without tag
	 * @throws IOException
	 */
	public FileLogger(String filePath, String tag) throws IOException {
		this(filePath);
		this.mTag = tag;
	}

	public void d(String tag, String msg) {
		write('d', msg, tag);
	}

	public void d(String msg) {
		write('d', msg);
	}

	public void e(String tag, String msg) {
		write('e', msg, tag);
	}

	public void e(String msg) {
		write('e', msg);
	}

	public void e(String tag, Exception e) {
		StackTraceElement[] stackTrace = e.getStackTrace();
		StringBuilder stack = new StringBuilder();
		stack.append(e.getMessage() + "\n");
		for (int i = 0; i < stackTrace.length; i++) {
			stack.append(stackTrace[i].toString() + "\n");
		}
		write('e', stack.toString());
	}

	public void i(String tag, String msg) {
		write('i', msg, tag);
	}

	public void i(String msg) {
		write('d', msg);
	}

	public void v(String tag, String msg) {
		write('v', msg, tag);
	}

	public void v(String msg) {
		write('d', msg);
	}

	public void w(String tag, String msg) {
		write('w', msg, tag);
	}

	public void w(String msg) {
		write('d', msg);
	}

	private void write(char lvl, String message) {
		String tag;
		if (mTag == null)
			tag = DEFAULT_TAG;
		else
			tag = mTag;
		write(lvl, message, tag);
	}

	private void write(char lvl, String message, String tag) {
		if (tag == null) {
			write(lvl, message);
			return;
		}

		String date = dateFormat.format(new Date());

		try {
			writer.append(date);
			writer.append(';');
			writer.append(lvl);
			writer.append(';');
			writer.append("null");
			writer.append(';');
			writer.append(tag);
			writer.append(';');
			writer.append(message);
			writer.append('\n');
			writer.flush();
		} catch (IOException e) {

		}
	}
}
